﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Kopytko.BoardGame
{
    public class Plansza
    {
        private Figura[][] Szachownica;
        public Plansza()
        {
            Szachownica = new Figura[8][];
            for (int i = 0; i < 8; i++)
            {
                Szachownica[i] = new Figura[8];
                for (int j = 0; j < 8; j++)
                {
                    Szachownica[i][j] = new Puste(new Pole(i, j));
                }
            }
            for (int i = 0; i < 8; i++)
            {
                Szachownica[i][1] = new Pionek(Color.Black, new Pole(i, 1));
                Szachownica[i][6] = new Pionek(Color.White, new Pole(i, 6));
            }
            Szachownica[0][0] = new Wieza(Color.Black, new Pole(0, 0));
            Szachownica[1][0] = new Kon(Color.Black, new Pole(1, 0));
            Szachownica[2][0] = new Laufer(Color.Black, new Pole(2, 0));
            Szachownica[3][0] = new Krolowa(Color.Black, new Pole(3, 0));
            Szachownica[4][0] = new Krol(Color.Black, new Pole(4, 0));
            Szachownica[5][0] = new Laufer(Color.Black, new Pole(5, 0));
            Szachownica[6][0] = new Kon(Color.Black, new Pole(6, 0));
            Szachownica[7][0] = new Wieza(Color.Black, new Pole(7, 0));
            Szachownica[0][7] = new Wieza(Color.White, new Pole(0, 7));
            Szachownica[1][7] = new Kon(Color.White, new Pole(1, 7));
            Szachownica[2][7] = new Laufer(Color.White, new Pole(2, 7));
            Szachownica[3][7] = new Krolowa(Color.White, new Pole(3, 7));
            Szachownica[4][7] = new Krol(Color.White, new Pole(4, 7));
            Szachownica[5][7] = new Laufer(Color.White, new Pole(5, 7));
            Szachownica[6][7] = new Kon(Color.White, new Pole(6, 7));
            Szachownica[7][7] = new Wieza(Color.White, new Pole(7, 7));

        }
        public Plansza(Plansza pierwowzor)
        {
            Szachownica = new Figura[8][];
            for (int i = 0; i < 8; i++)
            {
                Szachownica[i] = new Figura[8];
                for (int j = 0; j < 8; j++)
                {
                    Figura oryginal = pierwowzor.PobierzFigureZPola(new Pole(i, j));
                    if (oryginal is Krol)
                    {
                        Szachownica[i][j] = new Krol(oryginal);
                    }
                    else if (oryginal is Krolowa)
                    {
                        Szachownica[i][j] = new Krolowa(oryginal);
                    }
                    else if (oryginal is Kon)
                    {
                        Szachownica[i][j] = new Kon(oryginal);
                    }
                    else if (oryginal is Laufer)
                    {
                        Szachownica[i][j] = new Laufer(oryginal);
                    }
                    else if (oryginal is Wieza)
                    {
                        Szachownica[i][j] = new Wieza(oryginal);
                    }
                    else if (oryginal is Pionek)
                    {
                        Szachownica[i][j] = new Pionek(oryginal);
                    }
                    else
                    {
                        Szachownica[i][j] = new Puste(oryginal);
                    }
                }
            }
        }
        public Figura PobierzFigureZPola(Pole pole)
        {
            return Szachownica[pole.GetX()][pole.GetY()];
        }
        public void UstawFigureNaPolu(Figura figura, Pole pole)
        {
            Szachownica[pole.GetX()][pole.GetY()] = figura;
        }
        public bool PoleDostepneDoRuchu(Pole pole, Color kolor)
        {
            if (!PoleNaPlanszy(pole)) return false;
            Figura figura = PobierzFigureZPola(pole);
            return figura.GetKolor() == Color.None;
        }
        public bool PoleDostepneDoBicia(Pole pole, Color kolor)
        {
            if (!PoleNaPlanszy(pole)) return false;
            Figura figura = PobierzFigureZPola(pole);
            return figura.GetKolor() == Color.Przeciwnik(kolor);
        }
        public bool PoleDostepne(Pole pole, Color kolor)
        {
            if (!PoleNaPlanszy(pole)) return false;
            Figura figura = PobierzFigureZPola(pole);
            return figura.GetKolor() != kolor;
        }
        private bool PoleNaPlanszy(Pole pole)
        {
            return pole.GetX() >= 0 && pole.GetX() < 8 && pole.GetY() >= 0 && pole.GetY() < 8;
        }
        public bool PodDostepnymSzachem(Color kolor)
        {
            Color KolorSzachujacego = Color.Przeciwnik(kolor);
            List<Ruch> DostepneRuchyPrzeciwnika = this.ListaDostepnychRuchowDanegoKoloru(KolorSzachujacego);
            Figura SzachowanyKrol = this.PobierzKrolaDanegoKoloru(kolor);
            Pole PozycjaSzachowanegoKrola = SzachowanyKrol.GetPozycja();
            foreach (Ruch RuchPrzeciwnika in DostepneRuchyPrzeciwnika)
            {
                if (RuchPrzeciwnika.GetDokad() == PozycjaSzachowanegoKrola)
                {
                    return true;
                }
            }
            return false;
        }
        private List<Figura> ListaFigurDanegoKoloru(Color kolor)
        {
            List<Figura> ListaFigur = new List<Figura>();
            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    Figura figura = this.PobierzFigureZPola(new Pole(i, j));
                    if (figura.GetKolor() == kolor)
                    {
                        ListaFigur.Add(figura);
                    }
                }
            }
            return ListaFigur;
        }
        public List<Ruch> ListaDostepnychRuchowDanegoKoloru(Color kolor)
        {
            List<Figura> Figury = this.ListaFigurDanegoKoloru(kolor);
            List<Ruch> ListaRuchow = new List<Ruch>();
            foreach (Figura figura in Figury)
            {
                ListaRuchow.AddRange(figura.PobierzDostepneRuchy(this));
            }
            return ListaRuchow;
        }
        public List<Ruch> ListaLegalnychRuchowDanegoKoloru(Color kolor)
        {
            List<Figura> Figury = this.ListaFigurDanegoKoloru(kolor);
            List<Ruch> ListaRuchow = new List<Ruch>();
            foreach (Figura figura in Figury)
            {
                ListaRuchow.AddRange(figura.PobierzLegalneRuchy(this));
            }
            return ListaRuchow;
        }
        private Figura PobierzKrolaDanegoKoloru(Color kolor)
        {
            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    Figura kandydat = this.PobierzFigureZPola(new Pole(i, j));
                    if (kandydat is Krol && kandydat.GetKolor() == kolor) return kandydat;
                }
            }
            return null;
        }
        public void WykonajRuch(Ruch ruch)
        {
            if (ruch.JestRoszadaWLewo(this))
            {
                this.WykonajRuch(new Ruch(new Pole(0, ruch.GetSkad().GetY()), new Pole(3, ruch.GetSkad().GetY())));
            }
            else if (ruch.JestRoszadaWPrawo(this))
            {
                this.WykonajRuch(new Ruch(new Pole(7, ruch.GetSkad().GetY()), new Pole(5, ruch.GetSkad().GetY())));
            }
            Figura ruszana = this.PobierzFigureZPola(ruch.GetSkad());
            this.UstawFigureNaPolu(ruszana, ruch.GetDokad());
            ruszana.ZaznaczWykonanieRuchu();
            ruszana.SetPozycja(ruch.GetDokad());
            this.UstawFigureNaPolu(new Puste(ruch.GetSkad()), ruch.GetSkad());
        }
        public WynikRuchu AnalizujWynikRuchu(Ruch wykonany)
        {
            Figura RuszonaFigura = this.PobierzFigureZPola(wykonany.GetDokad());
            Color WykonujacyRuch = RuszonaFigura.GetKolor();
            Color OczekujacyNaRuch = Color.Przeciwnik(WykonujacyRuch);

            if (RuszonaFigura is Pionek)
            {
                if (WykonujacyRuch == Color.White && wykonany.GetDokad().GetY() == 0) return WynikRuchu.ZamianaPionka;
                if (WykonujacyRuch == Color.Black && wykonany.GetDokad().GetY() == 7) return WynikRuchu.ZamianaPionka;
            }
            if (this.PodDostepnymSzachem(OczekujacyNaRuch))
            {
                if (this.ListaLegalnychRuchowDanegoKoloru(OczekujacyNaRuch).Count == 0)
                {
                    return WynikRuchu.SzachMat;
                }
                else
                {
                    return WynikRuchu.Szach;
                }
            }
            if (this.ListaLegalnychRuchowDanegoKoloru(OczekujacyNaRuch).Count == 0)
            {
                return WynikRuchu.Pat;
            }
            return WynikRuchu.Normalny;
        }
    }
}
